package com.hk.commons.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.NamedThreadLocal;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class DateUtils {

    private static Logger logger = LoggerFactory.getLogger(DateUtils.class);

    //每一天的毫秒数
    private static final Integer MS_EVERY_DAY = 1000 * 60 * 60 * 24;

    /**
     * 精确到月的时间（默认）如：yyyy-MM
     */
    public static final String FORMAT_MONTH = "yyyy-MM";

    /**
     * 精确到天的时间如：yyyyMM
     */
    public static final String FORMAT_MONTH_N = "yyyyMM";

    /**
     * 精确到天的时间（默认）如：yyyy-MM-dd
     */
    public static final String FORMAT_SHORT = "yyyy-MM-dd";

    /**
     * 精确到天的时间如：yyyyMMdd
     */
    public static final String FORMAT_SHORT_N = "yyyyMMdd";

    /**
     * 精确到秒的时间，默认的pattern。 如：yyyy-MM-dd HH:mm:ss
     */
    public static final String FORMAT_LONG = "yyyy-MM-dd HH:mm:ss";

    /**
     * 英文全称 如：yyyyMMddHHmmss
     */
    public static final String FORMAT_LONG_N = "yyyyMMddHHmmss";

    /**
     * 精确到毫秒的时间 如：yyyy-MM-dd HH:mm:ss.S
     */
    public static final String FORMAT_FULL = "yyyy-MM-dd HH:mm:ss.S";

    /**
     * 精确到毫秒的时间,无分割 如：yyyyMMddHHmmssS
     */
    public static final String FORMAT_FULL_N = "yyyyMMddHHmmssS";

    /**
     * 精确到秒的小时时间 如：HH:mm
     */
    public static final String HOUR_SHORT = "HH:mm";

    /**
     * 精确到分的小时时间,无分割 如：HHmm
     */
    public static final String HOUR_SHORT_N = "HHmm";

    /**
     * 精确到秒的小时时间 如：HH:mm:ss
     */
    public static final String HOUR_LONG = "HH:mm:ss";

    /**
     * 精确到秒的小时时间,无分割 如：HHmmss
     */
    public static final String HOUR_LONG_N = "HHmmss";

    /**
     * 精确到毫秒的小时时间 如：HH:mm:ss.S
     */
    public static final String HOUR_FULL = "HH:mm:ss.S";

    /**
     * 精确到毫秒的小时时间,无分割 如：HHmmssS
     */
    public static final String HOUR_FULL_N = "HHmmssS";

    /**
     * 中文简写 如：2010年12月01日
     */
    public static final String FORMAT_SHORT_CN = "yyyy年MM月dd";

    /**
     * 中文全称 如：2010年12月01日 23时15分06秒
     */
    public static final String FORMAT_LONG_CN = "yyyy年MM月dd日  HH时mm分ss秒";

    /**
     * 精确到毫秒的完整中文时间
     */
    public static final String FORMAT_FULL_CN = "yyyy年MM月dd日  HH时mm分ss秒SSS毫秒";


    /**
     * ThreadLocal存放SimpleDateFormat
     */
    private static final NamedThreadLocal<SimpleDateFormat> dateFormatTL = new NamedThreadLocal<>(
            "DateUtil.dateFormat");

    /** 锁对象 */
    private static final Lock lock = new ReentrantLock();



    /**
     * 私有构造
     */
    private DateUtils() {
    }

    public static Date getNowDate(){
        return new Date();
    }

    public static Date getNowDate(String format){
        return parseDate(formatDate(getNowDate(),format),format);
    }

    public static Date parseDate(String strDate, String pattern) {
        try {
            return getDateFormat(pattern).parse(strDate);
        } catch (ParseException e) {
            logger.error("时间转换异常", e);
            return null;
        }
    }


    /**
     * 使用用户格式格式化日期
     *
     * @param date
     *            日期
     * @param pattern
     *            日期格式
     * @return
     */
    public static String formatDate(Date date, String pattern) {
        String returnValue = null;
        if (date != null) {
            returnValue = getDateFormat(pattern).format(date);
        }
        return returnValue;
    }

    /**
     * 获取ThreadLocal中SimpleDateFormat对象，默认格式
     *
     */
    public static SimpleDateFormat getDateFormat() {
        return getDateFormat(getDefulatPattern());
    }

    //默认的格式
    public static String getDefulatPattern() {
        return FORMAT_SHORT;
    }
    /**
     * 获取ThreadLocal中SimpleDateFormat对象,设置日期格式
     *
     * @param format 日期格式
     */
    public static SimpleDateFormat getDateFormat(String format) {
        SimpleDateFormat df = dateFormatTL.get();
        if (df == null) {
            lock.lock();
            df = dateFormatTL.get();
            if (df == null) {
                df = new SimpleDateFormat();
                dateFormatTL.set(df);
            }
            lock.unlock();
        }
        df.applyPattern(format);
        return df;
    }

}
